// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import AStar, { AStarPoint } from "./AStar";

const { ccclass, property } = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    @property(cc.Prefab)
    grid: cc.Prefab = null;

    @property(cc.Node)
    gridParent: cc.Node = null;

    private _map: Array<Array<number>> = [];

    private _nodeMap: Array<Array<cc.Node>> = [];

    private _gridSize: number = 40;

    private _aStar: AStar = null;

    private _currPath: Array<AStarPoint> = [];

    protected start(): void {
        //构建地图
        let width = 24, height = 16;
        for (let i = 0; i < height; i++) {
            this._map[i] = new Array(width).fill(0);
        }

        //生成图块
        let node: cc.Node;
        for (let i = 0; i < height; i++) {
            this._nodeMap[i] = this._nodeMap[i] || [];
            for (let j = 0; j < width; j++) {
                node = cc.instantiate(this.grid);
                node.parent = this.gridParent;
                node.x = j * this._gridSize;
                node.y = i * this._gridSize;
                this._nodeMap[i][j] = node;
            }
        }

        //生成障碍物
        for (let i = 0; i < height; i++) {
            for (let j = 0; j < width; j++) {
                if (Math.random() > 0.9) {
                    this._map[i][j] = -1;
                    this._nodeMap[i][j].color = cc.Color.GRAY;
                }
            }
        }

        //初始化astar
        this._aStar = new AStar();
        this._aStar.init(this._map);
        // AStar.enableBevel = true;
        AStar.debug = true;
    }

    onClick(event) {
        let gridPos = this.worldPos2GridPos(event.getLocation());
        if (this._map[gridPos.y][gridPos.x] == -1) return;
        this.clearPath();
        this._currPath = this._aStar.findPath(0, 0, gridPos.x, gridPos.y);
        this.renderPath();
    }

    worldPos2GridPos(worldPos: cc.Vec2): cc.Vec2 {
        return cc.v2(Math.floor(worldPos.x / this._gridSize), Math.floor(worldPos.y / this._gridSize));
    }

    clearPath() {
        for (let v of this._currPath) {
            this._nodeMap[v.y][v.x].color = cc.Color.WHITE;
        }
    }

    renderPath() {
        for (let v of this._currPath) {
            this._nodeMap[v.y][v.x].color = cc.Color.GREEN;
        }
    }
}
